﻿/**************************************************************
 *
 * 唯一标识：1f0dc49b-3482-43b3-9cdc-bf891df93e2e
 * 命名空间：Sgr.Domain.Repositories
 * 创建时间：2023/8/4 11:33:15
 * 机器名称：DESKTOP-S0D075D
 * 创建者：antho
 * 电子邮箱：fengqinhua2016@163.com
 * 描述：
 *
 **************************************************************/

using Microsoft.EntityFrameworkCore;
using Sgr.Domain.Entities.Auditing;
using Sgr.Domain.Repositories;

using Sgr.EntityFrameworkCore;
using Sgr.Exceptions;
using Sgr.Generator;
using Sgr.UPMS.Domain.Organizations;

namespace Sgr.UPMS.Infrastructure.Repositories
{
    /// <summary>
    /// 组织机构仓储实现
    /// </summary>
    /// <remarks>
    /// 实现了组织机构的基础操作，包括：
    /// - 树形结构管理
    /// - 组织状态维护
    /// - 编码唯一性校验
    /// </remarks>
    public class OrganizationRepository<TDbContext> :
        EfCoreTreeNodeBaseRepositoryOfTEntityAndTPrimaryKey<TDbContext, Organization, long>, IOrganizationRepository where TDbContext : UnitOfWorkDbContext
    {
        private readonly ISegmentNumIdGenerator _numberIdGenerator;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbContextProvider"></param>
        /// <param name="auditedOperator">审计操作者</param>
        /// <param name="numberIdGenerator">数字ID生成器</param>
        /// <exception cref="BusinessException">参数为空时抛出异常</exception>
        public OrganizationRepository(
            IDbContextProvider<TDbContext> dbContextProvider,
            IAuditedOperator auditedOperator,
            ISegmentNumIdGenerator numberIdGenerator)
            : base(dbContextProvider, auditedOperator)
        {
            _numberIdGenerator = numberIdGenerator ?? throw new ArgumentNullException(nameof(numberIdGenerator));
        }

        /// <summary>
        /// 检查并设置主键Id
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns></returns>
        protected override async Task CheckAndSetIdAsync(Organization entity, CancellationToken cancellationToken = default)
        {
            if (entity.Id == 0)
                entity.Id = await _numberIdGenerator.GetUniqueIdAsync(UpmsConstant.DEFAULT_SEGMENT_KEY, cancellationToken);
        }

        public async Task<bool> CodeIsUniqueAsync(string code, long? excludedId = null, CancellationToken cancellationToken = default)
        {
            Check.StringNotNullOrEmpty(code, nameof(code));

            var dbContext = await GetDbContextAsync(cancellationToken);
            var query = dbContext.Set<Organization>()
                                 .AsNoTracking()
                                 .Where(x => x.Code == code);

            // 排除指定ID的记录
            if (excludedId.HasValue && excludedId.Value > 0)
            {
                query = query.Where(x => x.Id != excludedId.Value);
            }

            // 返回 true 表示唯一，即没有找到重复记录
            return !await query.AnyAsync(cancellationToken);
        }

        /// <summary>
        /// 批量检查识别码是否存在
        /// </summary>
        /// <param name="identificationCodes">待检查的识别码列表</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>已存在的识别码集合</returns>
        public async Task<HashSet<string>> GetExistingIdentificationCodesAsync(
            IEnumerable<string> identificationCodes,
            CancellationToken cancellationToken = default)
        {
            // 空值验证
            if (identificationCodes == null || !identificationCodes.Any())
                return new HashSet<string>();

            var dbContext = await GetDbContextAsync(cancellationToken);

            var query = dbContext.Set<Organization>()
                                .AsNoTracking()
                                .Where(org => identificationCodes.Contains(org.IdentificationCode))
                                .Select(org => org.IdentificationCode);

            // 执行查询并返回结果
            var existingCodes = await query.ToListAsync(cancellationToken);
            return new HashSet<string>(existingCodes);
        }
    }
}